﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufArrangementArea.h"
#include "GnufQtWindow.h"
#include <QPushButton>
#include <QLabel>
#include <QCheckBox>
#include <QtCore/QPointer>

class QVBoxLayout;

namespace gnuf {
    class Info;
    class Pallet;
    class QtPalletHeader;
    class QtPalletFooter;
    class QtResizingGrip;
    class QtHeader;
    class QtHandle;

    class QtPalletButton final : public QPushButton
    {
        Q_OBJECT
    public:
        explicit QtPalletButton(QtPalletFooter *, const std::wstring &);
        explicit QtPalletButton(QtPalletHeader *, gcmp::OwnerPtr< Info > &, bool closeButton = false);
        explicit QtPalletButton(QtHeader*, gcmp::OwnerPtr< Info >&);
        virtual ~QtPalletButton() {}
        void setAsCurrent(bool);
        void setHighlightIfCurrent(bool highlignt) { m_highlightIfCurrent = highlignt; }
        void setStyle();

    protected:
        virtual void enterEvent(QEvent *) override;
        virtual void leaveEvent(QEvent *) override;
        virtual void paintEvent(QPaintEvent*) override;

    private:
        void onClicked(bool);

        QtHeader * m_qtHeader;
        QtPalletFooter * m_qtPalletFooter;
        gcmp::OwnerPtr< Info > m_info;
        QIcon m_icon;
        bool m_actAsTab;
        bool m_highlightIfCurrent;
        bool m_isCloseButton = false;
    };

    class QtPalletCheckBox final : public QCheckBox
    {
    public:
        explicit QtPalletCheckBox(QtPalletFooter *, const std::wstring &);
        virtual ~QtPalletCheckBox() {}

        std::wstring caption() { return this->text().toStdWString(); }
        void setStyle();
    private:
        void stateChanged(int);

    private:
        gcmp::OwnerPtr< Info > m_info;
        QtPalletFooter * m_qtPalletFooter;
    };
    
    class QtPallet : public gcmp::WeakReferenceable
    {
    public:
        explicit QtPallet(Pallet *);
        virtual ~QtPallet();
        void dispose();
        const Pallet * pallet() const { return m_wpPallet.Get(); }
        Pallet * pallet() { return m_wpPallet.Get(); }
        void refresh();
        virtual QWidget * qtWidget() = 0;
        virtual void initialize() = 0;
        virtual void onScaleFactorChanged() {}
        QtPalletFooter * qtFooter() const { return m_qtFooter; }

    protected:
        void initialize(int);
        void setPadding(int);
    private:
        gcmp::WeakPtr<Pallet> m_wpPallet;
        QVBoxLayout * m_qtLayout;
        QtPalletHeader * m_qtHeader;
        QtPalletFooter * m_qtFooter;
    };

    class QtPalletWithArrangementArea final
        : public QWidget
        , public QtPallet
        , public IArrangementAreaObserver
    {
    public:
        explicit QtPalletWithArrangementArea(Pallet *);
        virtual ~QtPalletWithArrangementArea();

    public:
        virtual void initialize() override;
        virtual void onScaleFactorChanged() override;

    protected:
        // Inherits from QtPallet...
        virtual QWidget * qtWidget() override;
        // Inherits from QWidget...
        virtual void showEvent(QShowEvent *) override;
        virtual void hideEvent(QHideEvent *) override;
        virtual void paintEvent(QPaintEvent *) override;
        virtual bool event(QEvent *) override;
        // Inherited from IArrangementAreaObserver...
        virtual void onArrangementAreaEvent(ArrangementAreaEvent *) override;
    private:
        QPointer< QtHandle > m_wpQtHandle;
        bool m_visibleWhenRestrained;
    };

    class QtPalletWithoutArrangementArea final 
        : public QtWindow
        , public IQtWindowUser
        , public QtPallet
    {
    public:
        explicit QtPalletWithoutArrangementArea(Pallet *);
        virtual ~QtPalletWithoutArrangementArea();

    public:
        virtual void initialize() override;
        void appear(bool synchronously);

    protected:
        // Inherits from IQtWindowUser...
        virtual void onScaleFactorChanged(const ScaleFactor &) override;
        virtual bool onIsMasked() const override;
        virtual bool onDoClose(const QtWindow *) override;
        // Inherits from QtPallet...
        virtual QWidget * qtWidget() override;
        // Inherits from QWidget...
        virtual void keyPressEvent(QKeyEvent *) override;
        virtual void enterEvent(QEvent *event) override;
        virtual void leaveEvent(QEvent *event) override;
        virtual void moveEvent(QMoveEvent *) override;
        virtual void resizeEvent(QResizeEvent *) override;
        virtual void paintEvent(QPaintEvent *) override;
        void onDragAndMove(int distanceX, int distanceY);

    private:
        void onHandleClosed();

        gcmp::OwnerPtr<QtResizingGrip> m_qtResizingGrip;
    };

}
